#ifndef __MEASURE_H__
#define __MEASURE_H__

#include <iostream>
#include <vector>
#include <utility>
#include <string>

typedef void (*MeasureFunc_t)(int problemSize, void **pData);
typedef double (*ModelFunc_t)(int problemSize);

class MeasureFuncCollection;
struct MeasureInterval;

//typedef std::vector<std::pair<std::string, MeasureFunc_t> > vectorMeasure_t;
typedef std::vector<MeasureFuncCollection> vectorMeasure_t;

class Measure
{
private:
	std::ostream *pOut, *pDebug;
	vectorMeasure_t measureFuncs;
	std::vector<MeasureInterval> intervals;
	double minMeasure;
	double repetitions;
	bool isOutputOwnFile;
public:
	Measure();
	void setOutstream(std::ostream& out);
	void setOutstream(const char *pszFilename);
	void setDebugOut(std::ostream& out);
	void addFunction(const char *pszName, MeasureFunc_t func, MeasureFunc_t init = 0, MeasureFunc_t cleanup = 0, ModelFunc_t model = 0);
	void addNewMeasureInterval(int start, int step, int stop);
	void addNewMeasure(int problemsize);
	void setMinMeasure(double min);
	void setRepetitions(int rep);

	void run();
};

class MeasureFuncCollection
{
	public:
	std::string name;
	MeasureFunc_t init;
	MeasureFunc_t func;
	MeasureFunc_t cleanup;
	ModelFunc_t model;
	MeasureFuncCollection(std::string name, MeasureFunc_t init, MeasureFunc_t func, MeasureFunc_t cleanup, ModelFunc_t model):name(name), init(init), func(func), cleanup(cleanup), model(model){}
};

struct MeasureInterval
{
	int start;
	int step;
	int stop;
};

#endif